package com.dd.cloud.user.service.doctor.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.config.obs.PathProperties;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.Base64Util;
import com.dd.cloud.common.utils.JsonUtils;
import com.dd.cloud.common.utils.UploadUtil;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.config.WebSocketServer;
import com.dd.cloud.user.entity.consult.WebSocketImMsg;
import com.dd.cloud.user.entity.doctor.DoctorSign;
import com.dd.cloud.user.entity.file.FileInfo;
import com.dd.cloud.user.mapper.doctor.DoctorSignMapper;
import com.dd.cloud.user.mq.MQConfig;
import com.dd.cloud.user.mq.RabbitSend;
import com.dd.cloud.user.req.doctor.DoctorWebSocketChatReq;
import com.dd.cloud.user.service.consule.IWebSocketImMsgService;
import com.dd.cloud.user.service.doctor.IDoctorSignService;
import com.dd.cloud.user.service.file.IFileInfoService;
import com.dd.cloud.user.util.Base64ToImgUtil;
import com.dd.cloud.user.vo.DelayMqVo;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;

/**
 * @author Lx
 * @version 1.0
 */
@Slf4j
@Service
public class DoctorSignServiceImpl extends ServiceImpl<DoctorSignMapper, DoctorSign> implements IDoctorSignService {
    @Autowired
    private FastFileStorageClient storageClient;
    @Autowired
    public PathProperties pathProperties;

    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private RabbitSend rabbitSend;

    @Autowired
    private IFileInfoService fileInfoService;

    @Autowired
    private IWebSocketImMsgService webSocketImMsgService;

    /**
     * 上传医生签名
     *
     * @param signBase
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadDoctorSign(String signBase) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        QueryWrapper<DoctorSign> qw = new QueryWrapper<>();
        qw.lambda().eq(DoctorSign::getDoctorId, loginInfo.getId());
        qw.lambda().eq(DoctorSign::getStatus, 1);
        DoctorSign ds = getOne(qw);
        if (ds == null) {
            ds = new DoctorSign();
            ds.setDoctorId(loginInfo.getId());
            ds.setStatus(1);
            ds.setCreateDate(LocalDateTime.now());
        }
        String signUrl = UploadUtil.uploadImage(signBase, storageClient);
        ds.setSignUrl(signUrl);
        ds.setUpdateDate(LocalDateTime.now());
        saveOrUpdate(ds);
    }

    /**
     * 上传医生签名 url地址
     *
     * @param signUrl
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadDoctorSignUrl(String signUrl) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        QueryWrapper<DoctorSign> qw = new QueryWrapper<>();
        qw.lambda().eq(DoctorSign::getDoctorId, loginInfo.getId());
        qw.lambda().eq(DoctorSign::getStatus, 1);
        DoctorSign ds = getOne(qw);
        if (ds == null) {
            ds = new DoctorSign();
            ds.setDoctorId(loginInfo.getId());
            ds.setStatus(1);
            ds.setCreateDate(LocalDateTime.now());
        }
        ds.setSignUrl(signUrl.replace(pathProperties.getImageServer(), ""));
        ds.setUpdateDate(LocalDateTime.now());
        saveOrUpdate(ds);
    }

    /**
     * 查询医生签名
     *
     * @param docId
     * @return
     */
    @Override
    public DoctorSign queryDoctorSign(Integer docId) {
        if (docId == null) {
            docId = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get().getId();
        }
        QueryWrapper<DoctorSign> qw = new QueryWrapper<>();
        qw.lambda().eq(DoctorSign::getDoctorId, docId);
        qw.lambda().eq(DoctorSign::getStatus, 1);
        DoctorSign ds = getOne(qw);
        return ds;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadDoctorSignH5(String signBase, Integer doctorId) {
        if (doctorId == null) {
            throw new ZekeException("医生id不能为空");
        }
        if (signBase == null) {
            throw new ZekeException("signBase不能为空");
        }
        try {
            webSocketServer.sendInfo(signBase, String.valueOf(doctorId));
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException("上传失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDoctorSignH5(String signBase, Integer doctorId) {
        MultipartFile multipartFile = Base64Util.base64ToMultipart(signBase);
        if (multipartFile == null) {
            return;
        }
        FileInfo fileInfo = fileInfoService.uploadSingleFile(multipartFile);
        QueryWrapper<DoctorSign> qw = new QueryWrapper<>();
        qw.lambda().eq(DoctorSign::getDoctorId, doctorId);
        qw.lambda().eq(DoctorSign::getStatus, 1);
        DoctorSign ds = getOne(qw);
        if (ds == null) {
            ds = new DoctorSign();
            ds.setDoctorId(doctorId);
            ds.setStatus(1);
            ds.setCreateDate(LocalDateTime.now());
        }
        log.info("签名图片路径:" + fileInfo.getFileUrl());
        ds.setSignUrl(fileInfo.getFileUrl());
        ds.setUpdateDate(LocalDateTime.now());
        saveOrUpdate(ds);
        log.info("~~~保存签名成功~~~");
    }


    /**
     * 私聊id_发送者类型_发送者id_接收者类型_接收者id
     */
    @Override
    public void sendWebsocketChat(DoctorWebSocketChatReq req) {
        try {
            LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
            Integer fromUserId = loginInfo.getId();
            Integer fromUserType = loginInfo.getType();
            WebSocketImMsg webSocketImMsg = new WebSocketImMsg();
            webSocketImMsg
                    .setType(req.getType())
                    .setToUserType(req.getToUserType())
                    .setToUser(req.getToUserId())
                    .setStatus(1)
                    .setFromUser(fromUserId)
                    .setFromUserType(fromUserType)
                    .setContent(req.getContent())
                    .setCreateDate(LocalDateTime.now())
                    .setPrivateGroupId(req.getPrivateGroupId());
            Boolean flag = webSocketImMsgService.save(webSocketImMsg);
            if (!flag) {
                log.info("消息存储失败");
            }
            if (req.getToUserType() != null && req.getToUserId() != null) {
                String uid = req.getPrivateGroupId() + "_" + req.getToUserType() + "_" + req.getToUserId();
                req.setSendDate(webSocketImMsg.getCreateDate());
                webSocketServer.sendInfo(JsonUtils.objectToStr(req), uid);
            }
            String sid = req.getPrivateGroupId() + "_" + fromUserType + "_" + fromUserId;
            req.setSendDate(webSocketImMsg.getCreateDate());
            webSocketServer.sendInfo(JsonUtils.objectToStr(req), sid);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException("发送消息失败");
        }
    }

    @Override
    public void testWebsocket(String content, String sid) throws IOException {
        webSocketServer.sendInfo(content, sid);
    }

    private void saveSignBase(String signBase, String doctorId) {
        Integer docId = null;
        try {
            if (!isNumeric4(doctorId)) {
                return;
            }
            docId = Integer.parseInt(doctorId);
        } catch (Exception e) {
            log.info("docId解析失败");
            return;
        }
        if (docId == null) {
            return;
        }
        QueryWrapper<DoctorSign> qw = new QueryWrapper<>();
        qw.lambda().eq(DoctorSign::getDoctorId, docId);
        qw.lambda().eq(DoctorSign::getStatus, 1);
        DoctorSign ds = getOne(qw);
        if (ds == null) {
            ds = new DoctorSign();
            ds.setDoctorId(docId);
            ds.setStatus(1);
            ds.setCreateDate(LocalDateTime.now());
        }
        String signUrl = UploadUtil.uploadImage(signBase, storageClient);
        ds.setSignUrl(signUrl);
        ds.setUpdateDate(LocalDateTime.now());
        saveOrUpdate(ds);
    }

    public static boolean isNumeric4(String str) {
        if (str == null) {
            return false;
        }
        for (char c : str.toCharArray()) {
            if (!Character.isDigit(c)) {
                return false;
            }
        }
        return true;
    }

}
